# -*- coding: utf-8 -*-
# This code written by ChanGOGOGO
"""
任务（通话）流经节点数据分析
"""
import pymysql
from util import (
    logging,
    query_es,
    data2beautify,
    date_slice,
    write_excel,
    calc_percent,
    db_ip,
    db_port,
    db_username,
    db_password,
    excel_save_dir,
)


class ExportTaskThroughNodeAnalysis:
    def __init__(self, ui_data):
        self.conn = pymysql.connect(
            host=db_ip,
            port=db_port,
            user=db_username,
            passwd=db_password,
            charset="utf8",
        )
        self.cursor = self.conn.cursor()
        self.company_id = ui_data.get("company_id")
        self.business_id = ui_data.get("business_id")
        self.business = ui_data.get("business")
        self.data_type = ui_data.get("data_type")
        self.call_type = ui_data.get("call_type")
        self.data_month = ui_data.get("data_date")
        self.start_time = ui_data.get("start_time")
        self.end_time = ui_data.get("end_time")
        self.task_ids = ui_data.get("target_datas")
        if self.call_type == "呼出":
            self.es_index = f"yicall_{self.company_id}_{self.business_id}_callout_session_ach_{self.data_month}"
        else:
            self.es_index = f"yicall_{self.company_id}_{self.business_id}_callout_session_in_ach_{self.data_month}"
        self.task_info = self.query_task_info()
        self.scene_info = self.query_scene_info()
        self.close_db()
        self.basic_excel_title = ["拨打日期", "任务ID", "任务名称", "所属场景"]

    def query_task_info(self):
        """查询任务信息"""
        if self.call_type == "呼出":
            sql = f"""select task_id,task_name from yicall_{self.company_id}.b_{self.business_id}_callout_task;"""
        else:
            sql = f"""select task_id,task_name from yicall_{self.company_id}.b_{self.business_id}_callout_task_in;"""
        logging.info(f"查询{self.business}任务信息SQL:\n{sql}")
        self.cursor.execute(sql)
        result = self.cursor.fetchall()
        task_info = dict()
        if result:
            task_info = {task_id: task_name for task_id, task_name in result}
        # logging.info(f"获取到{self.business}下的任务信息：\n{data2beautify(task_info)}")
        return task_info

    def query_scene_info(self):
        """查询场景信息"""
        sql = f"""select scene_id,scene_name from yicall_{self.company_id}.b_{self.business_id}_call_scene
        order by scene_id desc;"""
        self.cursor.execute(sql)
        result = self.cursor.fetchall()
        scene_info = {}
        if len(result) > 0:
            scene_info = {scene_id: scene_name for scene_id, scene_name in result}
        return scene_info

    def query_es_data(self, day_start_time, day_end_time):
        """查询每天拨打数据"""
        fields = ["calloutDialTime", "taskId", "sceneId", "turnList"]
        if len(self.task_ids) > 0:
            body = {
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"calloutConnectStatus": 100}},
                            {"terms": {"taskId": self.task_ids}},
                            {
                                "range": {
                                    "calloutFinishTime": {
                                        "gte": day_start_time,
                                        "lte": day_end_time,
                                    }
                                }
                            },
                        ]
                    }
                }
            }
        else:
            body = {
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"calloutConnectStatus": 100}},
                            {
                                "range": {
                                    "calloutFinishTime": {
                                        "gte": day_start_time,
                                        "lte": day_end_time,
                                    }
                                }
                            },
                        ]
                    }
                }
            }
        es_data = query_es(self.es_index, body, fields)
        return es_data

    def get_all_data(self):
        """"""
        all_data = {}
        day_slice = date_slice(self.start_time, self.end_time)  # 将起止时间按天切片
        for day in day_slice:
            start_time, end_time = day
            daily_data = self.query_es_data(start_time, end_time)
            for data in daily_data:
                dial_time = data.get("calloutDialTime")
                dial_date = dial_time.split(" ")[0]  # 获取拨打日期
                task_id = data.get("taskId")
                scene_id = data.get("sceneId")
                turn_list = data.get("turnList")
                find_dial_date = all_data.get(dial_date)  # 是否存在该拨打日期的统计数据
                if bool(turn_list) is True:
                    for turn in turn_list:
                        turn_holder = turn.get("turnHolder")
                        if turn_holder == "1":
                            node_name = turn.get("nodeName")
                            find_scene_id = all_data.get(scene_id, -1)
                            if find_scene_id == -1:
                                all_data[scene_id] = {
                                    dial_date: {
                                        task_id: {node_name: 1, "through_node_total": 1}
                                    },
                                    "alread_node_name": [node_name],
                                }
                            else:
                                find_dial_date = all_data.get(scene_id).get(
                                    dial_date, -1
                                )
                                if find_dial_date == -1:
                                    all_data[scene_id].update(
                                        {
                                            dial_date: {
                                                task_id: {
                                                    node_name: 1,
                                                    "through_node_total": 1,
                                                }
                                            }
                                        }
                                    )
                                else:
                                    find_task_id = (
                                        all_data.get(scene_id)
                                        .get(dial_date)
                                        .get(task_id, -1)
                                    )
                                    if find_task_id == -1:
                                        all_data[scene_id].get(dial_date).update(
                                            {
                                                task_id: {
                                                    node_name: 1,
                                                    "through_node_total": 1,
                                                }
                                            }
                                        )
                                    else:
                                        find_node_name = (
                                            all_data.get(scene_id)
                                            .get(dial_date)
                                            .get(task_id)
                                            .get(node_name, -1)
                                        )
                                        if find_node_name == -1:
                                            all_data[scene_id].get(dial_date).get(
                                                task_id
                                            ).update({node_name: 1})
                                        else:
                                            all_data[scene_id][dial_date][task_id][
                                                node_name
                                            ] += 1
                                        all_data[scene_id][dial_date][task_id][
                                            "through_node_total"
                                        ] += 1
                                if node_name not in all_data.get(scene_id).get(
                                    "alread_node_name"
                                ):
                                    all_data.get(scene_id).get(
                                        "alread_node_name"
                                    ).append(node_name)
        logging.info(f"查询到所有场景任务流经节点数据：\n{data2beautify(all_data)}")
        return all_data

    def handle_data(self):
        all_data = self.get_all_data()
        all_sheet_data = []
        for scene_id, scene_data in all_data.items():
            scene_name = self.scene_info.get(int(scene_id))
            scene_excel_title = self.basic_excel_title[:]
            scene_node_names = scene_data.get("alread_node_name")
            scene_sheet_data = []
            scene_sheet_data.append(scene_name)
            for scene_node_name in scene_node_names:
                scene_excel_title.append(scene_node_name)
                scene_excel_title.append("占比")
            scene_sheet_data.append(scene_excel_title)
            every_row_data = []
            for dial_date, task_data in scene_data.items():
                if dial_date == "alread_node_name":
                    continue
                for task_id, node_data in task_data.items():
                    task_name = self.task_info.get(int(task_id))
                    task_everyday_excel_data = [
                        "" for _ in range(len(scene_excel_title))
                    ]
                    through_node_total = node_data.get("through_node_total")
                    task_everyday_excel_data[0] = dial_date
                    task_everyday_excel_data[1] = task_id
                    task_everyday_excel_data[2] = task_name
                    task_everyday_excel_data[3] = scene_name
                    for node_name in scene_excel_title[4:-1:2]:
                        node_name_index = scene_excel_title.index(node_name)
                        through_current_node_total = node_data.get(node_name, 0)
                        through_node_precent = calc_percent(
                            through_current_node_total, through_node_total
                        )
                        task_everyday_excel_data[node_name_index] = (
                            through_current_node_total
                        )
                        task_everyday_excel_data[node_name_index + 1] = (
                            through_node_precent
                        )
                    every_row_data.append(task_everyday_excel_data)
            scene_sheet_data.append(every_row_data)
            all_sheet_data.append(scene_sheet_data)
        return all_sheet_data

    def close_db(self):
        self.cursor.close()
        self.conn.close()

    def export(self):
        all_sheet_data = self.handle_data()
        if bool(all_sheet_data) is True:
            file_name = f"{self.business}_({self.call_type}){self.data_type}"
            excel_name = write_excel(all_sheet_data, excel_save_dir, file_name)
            return {"code": 0, "excel_names": [excel_name], "msg": None}
        else:
            msg = (
                f"<font color=green>无法导出“{self.business}”的【{self.data_type}】，"
                f"原因：\n在{self.start_time}至{self.end_time}没有{self.call_type}数据！</font>"
            )
            return {"code": 1, "excel_names": None, "msg": msg}


if __name__ == "__main__":
    ...
